/*            Copyright(c) 2006-2008 Dave Sexton           *
 * http://www.codeplex.com/DocProject                      *
 * http://www.codeplex.com/DocProject/Project/License.aspx *
 ***********************************************************/
using System;
using System.Collections.Generic;
using System.Text;
using System.Collections.ObjectModel;
using System.ComponentModel;

namespace DaveSexton.DocProject.Sandcastle.TopicManagement
{
	[Serializable]
	[DisplayName("Category Filter"), Description("Includes or excludes topics based on categories such as API type and accessibility.")]
	public sealed class CategoryTopicFilter : TopicFilter
	{
		#region Public Properties
		public override string DisplayValue
		{
			get
			{
				string accessValue = (access == null) ? Resources.Text.AllEnumValues : TopicAccessibilityCollectionConverter.Default.ConvertToString(access);
				string typesValue = (types == null) ? Resources.Text.AllEnumValues : TopicTypeCollectionConverter.Default.ConvertToString(types);

				return string.Format(System.Globalization.CultureInfo.CurrentCulture,
					 Resources.Text.CategoryTopicFilterDisplayValue,
					 (string.IsNullOrEmpty(accessValue)) ? Resources.Text.AllEnumValues : accessValue, Environment.NewLine,
					 (string.IsNullOrEmpty(typesValue)) ? Resources.Text.AllEnumValues : typesValue);
			}
		}

		public override Type EditorType
		{
			get
			{
				return typeof(CategoryTopicFilterControl);
			}
		}

		public IEnumerable<TopicType> TopicTypes
		{
			get
			{
				return types;
			}
			set
			{
				types = new ReadOnlyCollection<TopicType>(new List<TopicType>(value));

				NotifyPropertyChanged("TopicTypes");
			}
		}

		public IEnumerable<TopicAccessibility> TopicAccess
		{
			get
			{
				return access;
			}
			set
			{
				access = new ReadOnlyCollection<TopicAccessibility>(new List<TopicAccessibility>(value));

				NotifyPropertyChanged("TopicAccess");
			}
		}
		#endregion

		#region Private / Protected
		private ReadOnlyCollection<TopicType> types;
		private ReadOnlyCollection<TopicAccessibility> access;
		#endregion

		#region Constructors
		/// <summary>
		/// Constructs a new instance of the <see cref="CategoryTopicFilter" /> class.
		/// </summary>
		public CategoryTopicFilter()
		{
			types = new ReadOnlyCollection<TopicType>(new List<TopicType>(0));
			access = new ReadOnlyCollection<TopicAccessibility>(new List<TopicAccessibility>(0));
		}

		/// <summary>
		/// Constructs a new instance of the <see cref="CategoryTopicFilter" /> class.
		/// </summary>
		public CategoryTopicFilter(IEnumerable<TopicType> types, IEnumerable<TopicAccessibility> access)
		{
			this.types = new ReadOnlyCollection<TopicType>(new List<TopicType>(types));
			this.access = new ReadOnlyCollection<TopicAccessibility>(new List<TopicAccessibility>(access));
		}

		/// <summary>
		/// Constructs a new instance of the <see cref="CategoryTopicFilter" /> class.
		/// </summary>
		public CategoryTopicFilter(CategoryTopicFilter clone)
			: base(clone)
		{
			types = new ReadOnlyCollection<TopicType>(new List<TopicType>(clone.types));
			access = new ReadOnlyCollection<TopicAccessibility>(new List<TopicAccessibility>(clone.access));
		}
		#endregion

		#region Methods
		public override bool IsMatch(Topic topic)
		{
			return (types.Count == 0 || types.Contains(topic.TopicType))
				&& (access.Count == 0 || access.Contains(topic.TopicAccess));
		}

		public override bool IsMatch(ReflectionApiElement element)
		{
			return (types.Count == 0 || types.Contains(element.TopicType))
				&& (access.Count == 0 || access.Contains(element.TopicAccess));
		}

		public override ITopicFilter Clone()
		{
			return new CategoryTopicFilter(this);
		}

		public override void Load(System.Xml.XmlReader reader)
		{
			base.Load(reader);

			types = new ReadOnlyCollection<TopicType>(Settings.Read<TopicTypeCollection>("types"));
			access = new ReadOnlyCollection<TopicAccessibility>(Settings.Read<TopicAccessibilityCollection>("access"));
		}

		public override void Save(System.Xml.XmlWriter writer)
		{
			if (types == null)
				Settings.Remove("types");
			else
				Settings.Write("types", new TopicTypeCollection(types));

			if (access == null)
				Settings.Remove("access");
			else
				Settings.Write("access", new TopicAccessibilityCollection(access));

			base.Save(writer);
		}
		#endregion
	}
}
